using System.Collections.Generic;

namespace GGEditor.API
{
    public interface IPluginNode
    {
        /// <summary>
        /// The plugin which defines this node
        /// </summary>
        IPlugin Plugin { get; }

        /// <summary>
        /// The full path to the node e.g. "/Workspace/MainMenu/File/Exit"
        /// </summary>
        string Path { get; }

		/// <summary>
		/// The parent node
		/// </summary>
		IPluginNode Parent { get; }

        /// <summary>
        /// The name of the node e.g. "Exit"
        /// </summary>
        string Name { get; }

        /// <summary>
        /// The class of node represented e.g. "MenuItem", "FileImporter"
        /// </summary>
        string Class { get; }

        /// <summary>
        /// The current runtime state of the plugin node
        /// </summary>
        PluginNodeState State { get; }

        /// <summary>
        /// Child nodes
        /// </summary>
        IEnumerable<IPluginNode> Nodes { get; }

        /// <summary>
        /// Get a child node by name
        /// </summary>
		IPluginNode GetChildNode(string name);

        /// <summary>
        /// The underlying object
        /// </summary>
		object Object { get; }

		/// <summary>
		/// Add a child node into the plugin tree
		/// </summary>
		void AddChild(IPluginNode child);

        /// <summary>
        /// Insert a child node into the plugin tree at the specified position
        /// </summary>
        void InsertChild(IPluginNode child, int position);

        /// <summary>
        /// Remove a child node from the plugin tree
        /// </summary>
        void RemoveChild(IPluginNode child);

		/// <summary>
		/// Notifies listeners when a child node has been added
		/// </summary>
		event PluginNodeEventHandler ChildAdded;

		/// <summary>
		/// Notifies listeners when a child node has been removed
		/// </summary>
		event PluginNodeEventHandler ChildRemoved;

        void Update();
    }

	public enum PluginNodeState
	{
		Enabled,    // currently functional
		Disabled,   // analogous to a "greyed-out" menu item
		Hidden      // disabled, but also invisible
	}

	public delegate void PluginNodeEventHandler(IPluginNode node, IPluginNode child, int position);

	public delegate PluginNodeState PluginNodeConditionDelegate(IPluginNode node);
}